﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace LolBot
{
    delegate void LolBotEventHandler(Object source, LolBotEvent e);

    class LolBotMessageParser
    {
        public event LolBotEventHandler PingEvent;
        public event LolBotEventHandler JoinEvent;
        public event LolBotEventHandler KickEvent;
        public event LolBotEventHandler RendezvousEvent;
        public event LolBotEventHandler MesserschmidtEvent;

        public event LolBotEventHandler ExitEvent;
        public event LolBotEventHandler OpEvent;
        public event LolBotEventHandler AddOpEvent;
        public event LolBotEventHandler RemoveOpEvent;
        public event LolBotEventHandler AddBadWordEvent;
        public event LolBotEventHandler RemoveBadWordEvent;
        public event LolBotEventHandler IgnoreEvent;
        public event LolBotEventHandler UnignoreEvent;
        public event LolBotEventHandler HelpEvent;
        public event LolBotEventHandler DateEvent;
        public event LolBotEventHandler SingEvent;
        public event LolBotEventHandler StopSingingEvent;
        public event LolBotEventHandler SayEvent;
        public event LolBotEventHandler MeEvent;

        public LolBotMessageParser()
        {
        }

        /**
	     * Parse the line that was written in the chat. This is a
	     * long method, please don't hit me for that.
	     * @param message The line that was written in the chat.
	     */
        public void Parse(IRCConfig config, String message)
        {
            /////////////////////////////////////////////////
            //  The following is for finding the source nick
            //  and command. Just a lot of crap.
            /////////////////////////////////////////////////
            String sourceNick = "";
            String[] lineWords = message.Substring(message.IndexOf(" :") + 2).Split(' ');
            String command = lineWords[0];
            List<String> arguments = new List<String>();
            if (lineWords.Length > 1)
            {
                for (int i = 1; i < lineWords.Length; i++)
                {
                    arguments.Add(lineWords[i]);
                }
            }

            String userInfo = message.Split(' ')[0];
            int exclamation = userInfo.IndexOf("!");
            int at = userInfo.IndexOf("@");
            if (userInfo.StartsWith(":"))
            {
                if (exclamation > 0 && at > 0 && exclamation < at)
                {
                    sourceNick = userInfo.Substring(1, exclamation - 1);
                }
            }

            if (sourceNick.StartsWith(":"))
            {
                sourceNick = sourceNick.Substring(1);
            }
            /////////////////////////////////////////////////
            /////////////////////////////////////////////////

            if (!sourceNick.Equals(config.nick))
            {
                Console.WriteLine(message);

                //Create the LolBotEvent that we will send to the listener.
                LolBotEvent e = new LolBotEvent(this, sourceNick, arguments, null, null);

                // Here we start to call the appropriate methods.
                if (message.StartsWith("PING") && PingEvent != null)
                {
                    String[] pingMessage = message.Split(' ');
                    e = new LolBotEvent(this, sourceNick, arguments, null, pingMessage[1]);
                    PingEvent(this, e);
                }
                else if (message.IndexOf("JOIN ") > -1 && JoinEvent != null)
                {
                    JoinEvent(this, e);
                }
                else if (message.IndexOf("KICK " + config.channel + " " + config.nick) > -1 &&
                    KickEvent != null)
                {
                    KickEvent(this, e);
                }
                else if (message.ToLower().Replace("[^A-Za-z0-9]", "")
                    .IndexOf("rendezvous") > -1 && RendezvousEvent != null)
                {
                    //If someone wrote the word "rendezvous" in the chat.
                    RendezvousEvent(this, e);
                }
                else if (message.ToLower().Replace("[^A-Za-z0-9]", "")
                        .IndexOf("messerschmidt") > -1 && MesserschmidtEvent != null)
                {
                    //If someone wrote the word "messerschmidt" in the chat.
                    MesserschmidtEvent(this, e);
                }

                else if (command.StartsWith(",") && command.Length > 1)
                {
                    switch (command.Substring(1))
                    {
                        case "exit":
                            if (ExitEvent != null)
                            {
                                ExitEvent(this, e);
                            }
                            break;
                        case "op":
                            if (OpEvent != null)
                            {
                                OpEvent(this, e);
                            }
                            break;
                        case "addOp":
                            if (AddOpEvent != null)
                            {
                                AddOpEvent(this, e);
                            }
                            break;
                        case "removeOp":
                            if (RemoveOpEvent != null)
                            {
                                RemoveOpEvent(this, e);
                            }
                            break;
                        case "addBadWord":
                            if (AddBadWordEvent != null)
                            {
                                AddBadWordEvent(this, e);
                            }
                            break;
                        case "removeBadWord":
                            if (RemoveBadWordEvent != null)
                            {
                                RemoveBadWordEvent(this, e);
                            }
                            break;
                        case "ignore":
                            if (IgnoreEvent != null)
                            {
                                IgnoreEvent(this, e);
                            }
                            break;
                        case "unignore":
                            if (UnignoreEvent != null)
                            {
                                UnignoreEvent(this, e);
                            }
                            break;
                        case "help":
                            if (HelpEvent != null)
                            {
                                HelpEvent(this, e);
                            }
                            break;
                        case "date":
                            if (DateEvent != null)
                            {
                                DateEvent(this, e);
                            }
                            break;
                        case "sing":
                            if (SingEvent != null)
                            {
                                SingEvent(this, e);
                            }
                            break;
                        case "stopSinging":
                            if (StopSingingEvent != null)
                            {
                                StopSingingEvent(this, e);
                            }
                            break;
                        case "say":
                            if (SayEvent != null)
                            {
                                SayEvent(this, e);
                            }
                            break;
                        case "me":
                            if (MeEvent != null)
                            {
                                MeEvent(this, e);
                            }
                            break;
                    }
                }
            }
        }
    }
}